﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace LocalOverride.Fiddler.Store
{
    public class MappingStore : IMappingStore
    {
        private readonly ILocalFileAccess localFileAccess;
        MappingEntryList entryList = new MappingEntryList();

        public MappingStore(ILocalFileAccess localFileAccess)
        {
            this.localFileAccess = localFileAccess;
            LoadEntriesFromDisk();
        }

        private void LoadEntriesFromDisk()
        {
            string settingsFilePath = GetSettingsFilePath();

            if (File.Exists(settingsFilePath))
            {
                using (FileStream fileStream = File.OpenRead(settingsFilePath))
                {
                    var xmlSerializer = GetXmlSerializer();
                    entryList = (MappingEntryList)xmlSerializer.Deserialize(fileStream);
                }
            }
        }

        public void Persist()
        {
            string settingsFilePath = GetSettingsFilePath();

            using (FileStream fileStream = File.Open(settingsFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                var xmlSerializer = GetXmlSerializer();
                xmlSerializer.Serialize(fileStream, entryList);
            }
        }

        private XmlSerializer GetXmlSerializer()
        {
            return new XmlSerializer(typeof(MappingEntryList));
        }

        private string GetSettingsFilePath()
        {
            string settingsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            return Path.Combine(settingsDirectory, "local-override.xml");
        }

        public void AddEntry(MappingEntry mappingEntry)
        {
            entryList.Entries.Add(mappingEntry);
        }

        public IEnumerable<MappingEntry> Entries
        {
            get { return entryList.Entries; }
        }

        public void Clear()
        {
            entryList = new MappingEntryList();
        }

        public void RemoveEntry(MappingEntry mappingEntry)
        {
            entryList.Entries.Remove(mappingEntry);
        }

        public IValidator ValidatorFor(MappingEntry mappingEntry)
        {
            return new MappingEntryValidator(mappingEntry, localFileAccess);
        }
    }
}